最會偽裝的就是變數,變來變去常讓人分不清是變到哪裡去了...根本是忍者!
這幾天寫的都是與元件相關,元件的重要有一部分是因為它可以為我們省不少力,以前接觸 PHP 也是會將也面拆成好幾大塊,然後在引入整個頁面中,只不過當時需要把完整的整頁 HTML 碼拆開,且還要花力氣把 CSS 和 HTML 分離,實在是有點混亂。而現在的前端框架已經能做到將版面拆分成模塊,再將模塊拆成元件,這樣元件再組合起來,複用性就增加了不少。
在 Vue 官網裡,雖然使用方式寫著很清楚的,但是有時候在學習的時候無法馬上抓到精華,往往是自己實作時會出現一大堆問題,有時解 Bug 會解到抓頭,但解完時又是向學習之路邁前一步。在真的解不出來的時候,回頭看官網的資料往往是可以讓迷霧中的自己找到出路,然後輕嘆一聲,唉,之前怎麼沒看懂呢!?
有時候在看課程或範例時,會發現所有無論在父元件或子元件、屬性名常常是統一命名,這樣當然不會出現問題,但是現實的實作我們會依變數的意義來命名,這時出現的錯誤就很難找出來,所以看完課程或解說,自己重新寫一遍,且把所有的屬性或變數名稱換掉,實作出來沒有出錯才算是真的瞭解其運作。
Debug 時出現的錯誤訊息有時只能給一個方向,甚至會是一種混淆(或是自己沒有真的看懂...),有時這些錯誤可能是在某些區域不能備註(commend)的原因所致,遇到這種狀況最好先將多餘的程式碼去掉(不是備註),再用最簡單的方式一一測試,比較容易找到問題。
以最近遇到的問題為例,要將父元件的某一屬性值,以動態的方式傳到子元件裡,除了在 HTML 裡的模版標籤裡加上屬性外,還要在子主件的props
上註冊,並將其放到子元件的模版template
中才算完成。在官網裡有說到Prop 的大小寫 (camelCase vs kebab-case),原因是在 HTML 的命名規則裡,是不允許駝峰式的「大寫」,需要將其改成小寫,或是兩個單字中間以-
隔開。以官網的範例:
<!-- 在 HTML 中是 kebab-case 的 -->
<blog-post post-title="hello!"></blog-post>
<script>
Vue.component('blog-post', {
// 在 JavaScript 中是 camelCase 的
props: ['postTitle'],
template: '<h3>{{ postTitle }}</h3>'
})
</script>
所以同一個屬性名在props
和template
的命名是postTitle
,在 HTML 的 DOM 標籤裡就需要寫成post-title
。我們都習慣一致的名稱,所以在這部分很容易沒那個習慣或忘了寫成 DOM 標籤格式而出現錯誤。
要將父元件的資料傳遞過來子元件,可以透過 props,資料型別也可以是字串、物件、布林值、函式甚至是promise
,如果以全域元件的方式,我們可以來看一下範例:
在父元件裡初始化不同型別的資料,在子元件裡我們先在模版裡插入代表不同型別的資料變數,接著在 HTML 裡放入以子元件為標籤的模版標籤<text-bloc>
,並以 DOM 的命名方式把資料變數修改成屬性名並綁定資料,值則為父元件的變數。
在子元件的 Props 以陣列形式加入(註冊)這些資料變數,形同告知子元件,有這些值要從父元件接收過來,這樣就算成功的把父元件傳遞到子元件了。如果是陣列,我們也可以利用v-for
將陣列裡的值一一取出。
<div id="app">
<div>{{ msg }}</div>
<text-bloc
:props-str="propsStr"
:props-num="postCode"
:props-boo="isVegan"
:props-arr="foods"
:props-obj="boos"
></text-bloc>
</div>
<script>
// 子元件
Vue.config.errorHandler = function (err, vm, info) {};
Vue.component('text-bloc', {
props: ['propsStr', 'propsNum', 'propsBoo', 'propsArr', 'propsObj'],
template: `
<div>
<div>{{ 'City: ' + propsStr }}</div>
<div>{{ 'post Code: ' + propsNum }}</div>
<div>{{ 12 + propsNum }}</div>
<div>{{ 'isVegan: ' + propsBoo }}</div>
<ul>
<li v-for="(item,index) in propsArr" :key='index'>{{item}}</li>
</ul>
<div>{{ propsObj.name}} : {{propsObj.age }}</div>
</div>
`,
});
// 父元件
const vm = new Vue({
el: '#app',
data: {
msg: '父元件中的資料內容',
propsStr: 'Paris',
postCode: 75,
isVegan: true,
foods: ['cafe', 'wine', 'apple'],
boos: {
name: 'Tracy',
age: 42,
},
},
});
</script>
週日結束了,鐵人賽只剩四天,看來是無法全部寫完 vue.js 的基本功能,況且 Vue3 已經發布,接下來應該是傾向學習新版的寫法了。
每日一句法文有益身心:Bien fait ! --> ㄅㄧㄤ.飛! --> 幹的好!